package org.NooLab.itexx.app.controller;

import java.awt.Component;

import org.NooLab.itexx.ITexxWindowCommons;
import org.NooLab.itexx.app.controller.analyzer.SerDocumentScoring;
import org.NooLab.itexx.app.controller.results.SearchEngineResultItem;
import org.NooLab.itexx.app.gui.StackedPanel;
import org.NooLab.itexx.app.gui.StackedPanelProducer;
import org.NooLab.itexx.app.gui.StackedPanels;
import org.NooLab.itexx.app.gui.definition.ITexxWindowGuiIntf;
import org.NooLab.itexx.app.gui.handlers.PanelText;
import org.NooLab.utilities.datatypes.IndexDistance;
import org.NooLab.utilities.datatypes.IndexedDistances;
import org.NooLab.utilities.logging.PrintLog;



/**
 * 
 * this runs its own thread, sending the results to the panel list
 * 
 * From there, the user will select any of the panels by double clicking (which stops the clipboard)
 * 
 * this object is hosted by appCommons, the global list it is working on gets updated by ResultsDigester
 * such we have the classical queue pattern
 * 
 * this global list is hosted by the SessionManager
 * 
 */
public class FoundResultsGuiUpdater {

	ITexxWindowCommons appCommons;
	SessionManager smgr ;
	ITexxWindowGuiIntf windowGui;
	
	int maxNumberOfPanels = 5; // from properties
	private IndexedDistances panelMap;
	private StackedPanelProducer panelProducer;
	private StackedPanels stackedPanels;
	ScoredSerDocuments scoredSerDocs;
	
	boolean panelHandlingIsRunning=false;
	
	// DisplayItems would be a further instance for handling the text and the panels, e.g. for persistence
	DisplayItems displayItems;
	IndexedDistances waitingLogicalPanels;
	
	PanelHandling panelHandling;
	PrintLog out;
	private int panelsMaxNumber;
	boolean adoptingPanelsMap;
	
	
	// ========================================================================
	public FoundResultsGuiUpdater( ITexxWindowCommons commons,
								   ITexxWindowGuiIntf windowGui,
								   int maxNumberOfPanels) {
		
		appCommons = commons;
		this.windowGui = windowGui;
		smgr = appCommons.getSessionManager() ;
	
		panelMap = appCommons.getModelController().getPanelMap() ;
		panelProducer = appCommons.getPanelProducer() ;
		
		out = appCommons.out;
		
		this.maxNumberOfPanels = maxNumberOfPanels;
		waitingLogicalPanels = new IndexedDistances(); 
		
		panelsMaxNumber = appCommons.getAppProperties().getIniPreferences().getPanelsMaxNumber();
		
		panelHandling = new PanelHandling(this);
		// late init needed
		// stackedPanels = panelProducer.getPanels() ;
		// establishListOfPanels();
	}
	// ========================================================================
	
	public void close(){
		
		panelHandlingIsRunning = false;
		out.delay(150) ;
	}
	
	
	public void reset() {
		//  
		// waitingLogicalPanels.clear();
	}

	/**
	 * refers to the physical panels
	 */
	private void establishListOfPanels(){
	
		// panelMap
		
		for (int i=0;i<stackedPanels.size();i++){
			
			
		}// i->
		
	}


	public void refreshItems(ScoredSerDocuments scoredSerDocs, IndexedDistances panelMap, boolean clearlist) {
		//
		if (displayItems==null){
			displayItems = new DisplayItems(this) ;
			this.scoredSerDocs = scoredSerDocs;
		}
		
		importCurrentPanelMap( panelMap, clearlist );
	}
	
	
	private void importCurrentPanelMap(IndexedDistances panelMap, boolean clearlist) {
		// 
		
		IndexDistance pmItem;
		adoptingPanelsMap=true;
		if (clearlist){
			waitingLogicalPanels.clear();
		}
		for (int i=0;i<panelMap.size();i++){
			waitingLogicalPanels.add( new  IndexDistance(panelMap.getItem(i)));
		}
		int n= waitingLogicalPanels.size();
		adoptingPanelsMap=false;
		
	}
	
	/**
	 * 
	 * this returns a StackedPanel Object,  which has a setText method
	 * 
	 * @param index
	 */
	protected StackedPanel getPhysicalDisplayPanel(int index){
		
		if (panelProducer==null){
			panelMap = appCommons.getModelController().getPanelMap() ;
			panelProducer = appCommons.getPanelProducer() ;
		}
		StackedPanels sPanels = panelProducer.getPanels();
		StackedPanel sPanel = null;
		
		
		
		if ((index>=0) && (index>sPanels.size())){
			if (index < panelsMaxNumber){
				panelProducer.provideMissingPanels(index);
			}
		}
		if ((index>=0) && (index<sPanels.size())){
			sPanel = sPanels.getItem(index);
		}
		
		return sPanel;
	}

	public String preparePaneltext(ScoredSerDocument serDoc, int useSummaryText) {
		// 
		String ptext;
		
		if (useSummaryText>0){
			ptext = serDoc.getSummaryText() ;
		}else{
			ptext = serDoc.getDocContentText();
		}
		
		if (ptext.length() >150){
			ptext=ptext.substring(0,150);
		}
		
		// we need the title as identified by the search engine, of the content of the first <h[]> tag..
		
		return ptext;
	}

	public void prepareFinalList() {
		// 
		IndexedDistances globalUrlList ;
		IndexDistance globurlitem ;
		String urlStr;
		ScoredSerDocument serDoc = null;
		
		/*
		 * the list scoredSerDocs is a derivative from the list .... which is the working list
		 * 
		 */
		
		// we should sort the panelMap again...
		
		globalUrlList = appCommons.getModelController().getGlobalUrlList() ;
		globalUrlList.sort(-1);
		
		int z=0;
		for (int i=0;i<globalUrlList.size();i++){
			
			globurlitem = globalUrlList.getItem(i);
			urlStr = globurlitem.getGuidStr() ;
			out.print(2, ""+globurlitem.getIndex()+" , "+globurlitem.getIndex2()+", "+ urlStr) ;

			
			int ix = globurlitem.getIndex2();
if (scoredSerDocs==null){
int k;
k=0;
}
			if ((scoredSerDocs!=null) && (ix<scoredSerDocs.size())&& (ix>=0)){
				serDoc = scoredSerDocs.get(ix) ;
				// 1=summary text 2=show search engine Title 3=both
				// make it a preference option
				printSerToPanel(z, serDoc, true, 1);

				z++;
			}
		}//->
		
	}
	

	
	/**
	 * 
	 * @param pix            the physical panel index 
	 * @param serDoc         the item structure
	 * @param urltoTooltip   url will be showing up as tooltip (balloon window)
	 * @param useSummaryText 1=summary text 2=show search engine Title 3=both
	 */
	protected void printSerToPanel(int pix, ScoredSerDocument serDoc, boolean urltoTooltip, int useSummaryText) {
		                       // TODO change this to ScoredSerDocumentIntf... 
		StackedPanel sPanel ;
		String panelText;
		
		sPanel = getPhysicalDisplayPanel(pix);
		
		if ((pix>0) && (sPanel==null)){
			
			if (pix<maxNumberOfPanels){
				// add a new
				sPanel = panelProducer.addPanel();
				
			}else{
				// replace one with a lower score, ...yet it should already be sorted...
				
				// if no replace, save it elsewhere (to a "virtual page")
			}
			
		}
		if (sPanel!=null){
			serDoc.setCheckedForDisplay(true);
			
			// FIXME: again checking the panels ???
			String str ="" ;
			if (appCommons.getAppProperties().getIniPreferences().getShowPanelEnumeration()>0){
				str = ""+(pix+1)+".  " ;
			}

			panelText = str + preparePaneltext( serDoc, useSummaryText )	; 
			// creating an html string for the EditorPane
			
			// update the displayitem
			sPanel.setPanelText(panelText) ;
			sPanel.setTooltipText(serDoc.getDocUrl());
		}
		
	}

	
}


class PanelHandling implements Runnable {

	Thread serscThrd ;
	FoundResultsGuiUpdater parent;
	private StackedPanel sPanel;
	private ScoredSerDocument serDoc;
	private String panelText;
	
	// ..........................................
	public PanelHandling(FoundResultsGuiUpdater gup){
		
		parent = gup;

		serscThrd = new Thread(this,"serscThrd") ;
		serscThrd.start();
	}
	// ..........................................
	
	
	@Override
	public void run() {
		boolean isWorking = false;
		
		parent.out.printErr(2, "... display updating process started working...  waiting for items") ;
		
		parent.panelHandlingIsRunning = true; 
		
		while (parent.panelHandlingIsRunning){

			
			if ((isWorking==false) && (parent.waitingLogicalPanels.size()>0) && (parent.adoptingPanelsMap==false)){
				isWorking = true;
				
				IndexDistance logPanel = parent.waitingLogicalPanels.getItem(0) ;
				parent.waitingLogicalPanels.getItems().remove(0) ;
				
				/*
				 * now, this "logPanel" has a score...
				 * we have to test which position of the display items we have to update
				 */

				int dix = logPanel.getIndex(); // secondary index instead ???
				serDoc = parent.scoredSerDocs.get(dix) ;
				
				if ((serDoc==null) || (serDoc.isCheckedForDisplay())){
					isWorking = false;
					continue;
				}
				
				parent.printSerToPanel( dix,serDoc ,true,1);
				
				
				
				if (parent.appCommons.getModelController().isUserBreak()){
					parent.displayItems.clear();
					parent.panelHandlingIsRunning = false;
				}
				isWorking = false;
				
			}else{
				
				if (parent.out!=null){
					parent.out.delay(115);
				}
			}
			
		}// ->>>>>>>>
		
		parent.panelHandlingIsRunning = false;
		
		parent.out.printErr(2, "... display updating process stopped working.") ;
	}
		
	
}
